﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;

namespace GoodStuff.Web.Controls
{
    /// <summary>
    /// Extenstion which can be used on a System.Web.UI.WebControls.DropDownList
    /// </summary>
    public static class ListControlExtensions
    {
        /// <summary>
        /// Insert a Listitem (Text = "-- Maak een keuze --", Value = "") as first item.
        /// </summary>
        /// <param name="control"></param>
        public static void InsertDefault(this ListControl control)
        {
            control.Items.Insert(0, new ListItem("-- Maak een keuze --", string.Empty));
        }

        /// <summary>
        /// Insert a Listitem with Value="" and the given (display)Text as first item.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="displayText">Text to display</param>
        public static void InsertDefault(this ListControl control, string displayText)
        {
            control.Items.Insert(0, new ListItem(displayText, string.Empty));
        }

        /// <summary>
        /// Insert a Listitem with the given text and value as first item.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="displayText">Text to display</param>
        /// <param name="value">The value of the listitem that will be created</param>
        public static void InsertDefault(this ListControl control, string displayText, string value)
        {
            control.Items.Insert(0, new ListItem(displayText, value));
        }

        /// <summary>
        /// Converts the SelectedValue to a Guid. Throws on invalid Guid
        /// </summary>
        /// <param name="control"></param>
        /// <returns>assigned GUID</returns>
        public static Guid SelectedValueAsGuid(this ListControl control)
        {
            if (control.SelectedIndex == -1)
                throw new ArgumentException("No listitem has been selected for the ListControl (DropDownList,RadioButtonList etc). SelectedValue couldn't be converted to a GUID. ListControl with ID " + control.ID, "SelectedValue");

            try
            {
                return new Guid(control.SelectedValue);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a GUID. ListControl with ID " + control.ID, "SelectedValue", ex);
            }
        }

        /// <summary>
        /// Converts the SelectedValue to a Nullable Guid. Throws on invalid Guid
        /// </summary>
        /// <param name="control"></param>
        /// <returns>Nullable Guid</returns>
        public static Guid? SelectedValueAsGuidNullable(this ListControl control)
        {
            if (string.IsNullOrEmpty(control.SelectedValue))
            {
                return null;
            }

            try
            {
                return new Guid(control.SelectedValue); //could throw
            }
            catch (Exception ex)
            {
                throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a nullable GUID. ListControl with ID " + control.ID, "SelectedValue", ex);
            };
        }

        /// <summary>
        /// Converts the SelectedValue to a Int32. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>assigned Int32</returns>
        public static int SelectedValueAsInteger(this ListControl control)
        {
            if (control.SelectedIndex == -1)
                throw new ArgumentException("No listitem has been selected for the ListControl (DropDownList,RadioButtonList etc). SelectedValue couldn't be converted to a Int32. ListControl with ID " + control.ID, "SelectedValue");

            try
            {
                return int.Parse(control.SelectedValue);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a Int32 or value is too large for an Int32. ListControl with ID " + control.ID, "SelectedValue", ex);
            }
        }

        /// <summary>
        /// Converts the SelectedValue to a nullable Int32. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>Nullable Int32</returns>
        public static int? SelectedValueAsIntegerNullable(this ListControl control)
        {
            if (string.IsNullOrEmpty(control.SelectedValue) == false)
            {
                int result;
                if (int.TryParse(control.SelectedValue, out result))
                {
                    return result;
                }
                else
                {
                    throw new ArgumentException(string.Format("SelectedValue '{0}' of ListControl (DropDownList,RadioButtonList etc) with ID {1} couldn't be converted to a nullable Int32 or is too large for an Int32.", control.SelectedValue, control.ID), "SelectedValue");
                }
            }
            return null;
        }

        /// <summary>
        /// Converts the SelectedValue to a Int64 (long). Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>assigned Int64</returns>
        public static long SelectedValueAsLong(this ListControl control)
        {
            if (control.SelectedIndex == -1)
                throw new ArgumentException("No listitem has been selected for the ListControl (DropDownList,RadioButtonList etc). SelectedValue couldn't be converted to a Int64. ListControl with ID " + control.ID, "SelectedValue");

            try
            {
                return int.Parse(control.SelectedValue);
            }
            catch (Exception ex)
            {
                throw new ArgumentException(string.Format("SelectedValue '{0}' of ListControl (DropDownList,RadioButtonList etc) with ID {1} couldn't be converted to a Int64.", control.SelectedValue, control.ID), "SelectedValue", ex);
            }
        }

        /// <summary>
        /// Converts the SelectedValue to a nullable Int64. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>Nullable Int64</returns>
        public static long? SelectedValueAsLongNullable(this ListControl control)
        {
            if (string.IsNullOrEmpty(control.SelectedValue) == false)
            {
                long result;
                if (long.TryParse(control.SelectedValue, out result))
                {
                    return result;
                }
                else
                {
                    throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a nullable Int64. ListControl with ID " + control.ID, "SelectedValue");
                }
            }
            return null;
        }

        /// <summary>
        /// Converts the SelectedValue to a Decimal. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>assigned Decimal</returns
        public static decimal SelectedValueAsDecimal(this ListControl control)
        {
            if (control.SelectedIndex == -1)
                throw new ArgumentException("No listitem has been selected for the ListControl (DropDownList,RadioButtonList etc). SelectedValue couldn't be converted to a Decimal. ListControl with ID " + control.ID, "SelectedValue");

            try
            {
                return decimal.Parse(control.SelectedValue);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a Decimal or value is too large for an Decimal. ListControl with ID " + control.ID, "SelectedValue", ex);
            }
        }

        /// <summary>
        /// Converts the SelectedValue to a nullable Decimal. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>Nullable Decimal</returns>
        public static decimal? SelectedValueAsDecimalNullable(this ListControl control)
        {
            if (string.IsNullOrEmpty(control.SelectedValue) == false)
            {
                decimal result;
                if (decimal.TryParse(control.SelectedValue, out result))
                {
                    return result;
                }
                else
                {
                    throw new ArgumentException(string.Format("SelectedValue '{0}' of ListControl (DropDownList,RadioButtonList etc) with ID {1} couldn't be converted to a nullable Decimal or is too large for an Decimal.", control.SelectedValue, control.ID), "SelectedValue");
                }
            }
            return null;
        }

        /// <summary>
        /// Converts the SelectedValue to a Boolean. Throws on not true|false text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>assigned Boolean</returns
        public static bool SelectedValueAsBoolean(this ListControl control)
        {
            if (control.SelectedIndex == -1)
                throw new ArgumentException("No listitem has been selected for the ListControl (DropDownList,RadioButtonList etc). SelectedValue couldn't be converted to a Boolean. ListControl with ID " + control.ID, "SelectedValue");

            try
            {
                return bool.Parse(control.SelectedValue);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("SelectedValue of ListControl (DropDownList,RadioButtonList etc) couldn't be converted to a Boolean (should be true or false - case insensitve). ListControl with ID " + control.ID, "SelectedValue", ex);
            }
        }

        /// <summary>
        /// Converts the SelectedValue to a nullable Boolean. Throws on not numeric text
        /// </summary>
        /// <param name="control"></param>
        /// <returns>Nullable Boolean</returns>
        public static bool? SelectedValueAsBooleanNullable(this ListControl control)
        {
            if (string.IsNullOrEmpty(control.SelectedValue) == false)
            {
                bool result;
                if (bool.TryParse(control.SelectedValue, out result))
                {
                    return result;
                }
                else
                {
                    throw new ArgumentException(string.Format("SelectedValue '{0}' of ListControl (DropDownList,RadioButtonList etc) with ID {1} couldn't be converted to a nullable Boolean (should be empty, or true or false - case insensitve).", control.SelectedValue, control.ID), "SelectedValue");
                }
            }
            return null;
        }

    }
}
